//
//	QSEclipseObjectSource.m
//
//   Copyright 2007 Brad Reynolds
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

#import "QSEclipseObjectSource.h"
#import "QSEclipsePlugin.h"
#import "QSEclipseImage.h"
#import <QSCore/QSCatalogEntry.h>

#define ICONSIZE NSMakeSize(128,128)

@implementation QSEclipseObjectSource

- (BOOL)indexIsValidFromDate:(NSDate *)indexDate forEntry:(NSDictionary *)theEntry {
	// TODO
	return NO;
}

- (NSArray *) objectsForEntry:(NSDictionary *)theEntry{
	NSUserDefaults *defaults = [[QSEclipsePlugin sharedInstance] userDefaults];
	NSString *searchPath = [[defaults stringForKey:QSEclipseWorkspaceSearchPath] stringByExpandingTildeInPath];
	NSSet *excludePaths = [self expandPathArray:[defaults arrayForKey:QSEclipseWorkspaceSearchPathExcludes]];
	NSMutableArray *objects=[NSMutableArray arrayWithCapacity:1];
	
	[self findWorkspacesAtPath:searchPath catalog:objects excludes:excludePaths defaults:defaults];
	
	return objects;
}

- (void) findWorkspacesAtPath:(NSString *) path catalog:(NSMutableArray *) catalog excludes:(NSSet *) excludes defaults:(NSUserDefaults *) defaults {
	NSFileManager *fileManager = [NSFileManager defaultManager];
	NSArray *files = [fileManager directoryContentsAtPath:path];
	
	if (files == nil) {
		return;
	}
	
	NSString *file = nil;
	NSEnumerator *enumerator = [files objectEnumerator];
	
	while (file = [enumerator nextObject]) {
		//skip hidden files (there is a more correct way of doing this...)
		if ([file length] > 0 && [file characterAtIndex:0] == '.') {
			continue;
		}
		
		//Skip any path that it so be excluded
		NSString *filePath = [path stringByAppendingPathComponent:file];
		if ([excludes containsObject:filePath]) {
			continue;
		}
			
		BOOL isDir = NO;
		if ([fileManager fileExistsAtPath:filePath isDirectory:&isDir] && isDir) {
			NSString *metadataPath = [filePath stringByAppendingPathComponent:@".metadata"];
			
			if ([fileManager fileExistsAtPath:metadataPath isDirectory:&isDir] && isDir) {
				[catalog addObject:[self newWorkspace:filePath]];
						
				NSString *name = [NSString stringWithFormat:[defaults stringForKey:QSEclipseWorkspaceLogLabel], [filePath lastPathComponent]];
				QSObject *entry = [QSObject objectWithName:name];
				filePath = [metadataPath stringByAppendingPathComponent:@".log"];
				[entry setIdentifier:[NSString stringWithFormat:@"eclipse.org/log/%@", filePath]];
				[entry setObject:[NSArray arrayWithObject:filePath] forType:NSFilenamesPboardType];
				
				NSImage *fileIcon = [[[NSWorkspace sharedWorkspace] iconForFile:filePath] copy];
				[fileIcon setSize:ICONSIZE];
				[entry setIcon:[fileIcon withEclipseDecoration]];
				[fileIcon release];
				[entry setRetainsIcon:YES];
				[entry setPrimaryType:QSEclipseWorkspaceLogFileType];
				[catalog addObject:entry];
			} else {
				[self findWorkspacesAtPath:filePath catalog:catalog excludes:excludes defaults:defaults];
			}
		}
	}
}

//Returns an initialized NSSet.  nil is accepted for the pathArray.
- (NSSet *) expandPathArray:(NSArray *) pathArray {
	if (pathArray == nil) {
		return [NSSet set];
	}

	NSMutableSet *set = [NSMutableSet setWithCapacity:[pathArray count]];
	NSEnumerator *pathEnum = [pathArray objectEnumerator];
	NSString *path;
	
	while (path = [pathEnum nextObject]) {
		[set addObject:[path stringByExpandingTildeInPath]];
	}
	
	return set;
}

//returns a new QSObject representing a workspace at the provided path
- (QSObject *) newWorkspace:(NSString *) path {
	NSString *workspaceName = [path lastPathComponent];

	NSUserDefaults *defaults = [[QSEclipsePlugin sharedInstance] userDefaults];
	NSString *name = [NSString stringWithFormat:[defaults stringForKey:QSEclipseWorkspaceLabel], workspaceName];
	QSObject *catalogObject = [QSObject objectWithName:name];
	[catalogObject setObject:path forType:QSEclipseWorkspaceType];
	
	NSImage *fileIcon = [[[NSWorkspace sharedWorkspace] iconForFile:path] copy];
	[fileIcon setScalesWhenResized:YES];
	[fileIcon setSize:ICONSIZE];
	
	NSImage *eclipseImage = [fileIcon withEclipseDecoration];
	[fileIcon release];
	
	[eclipseImage setScalesWhenResized:YES];
	
	[catalogObject setIcon:eclipseImage];
	[catalogObject setRetainsIcon:YES];
	
	//Setting the primary type will display the Ecilpse icon and not the folder icon.
	[catalogObject setPrimaryType:QSEclipseWorkspaceType];
	[catalogObject setIdentifier:[NSString stringWithFormat:@"eclipse.org/workspace/%@", path]];
	
	return catalogObject;
}

//invoked when attempting to display the catalog in QS preferences
- (NSImage *) iconForEntry:(NSDictionary *)theEntry {
	return [[QSEclipsePlugin sharedInstance] eclipseImage];
}

//loads the recent workspaces of an Eclipse.app instance
- (BOOL)loadChildrenForObject:(QSObject *)object {
	NSString *eclipsePath = [object primaryObject];
	eclipsePath = [eclipsePath stringByDeletingLastPathComponent];
	NSString *prefsPath = [eclipsePath stringByAppendingPathComponent:@"configuration/.settings/org.eclipse.ui.ide.prefs"];
	
	NSFileManager *fileManager = [NSFileManager defaultManager];
	if ([fileManager fileExistsAtPath:prefsPath]) {
		NSError *error;
		NSString *contents = [[NSString alloc] initWithContentsOfFile:prefsPath encoding:NSUTF8StringEncoding error:&error];
		
		if (contents != nil) {
			NSRange range = [contents rangeOfString:@"\nRECENT_WORKSPACES="];
			
			if (range.location != NSNotFound) {
				NSRange lineRange = [contents lineRangeForRange:NSMakeRange(range.location + 1, range.length)];
				NSString *workspaces = [contents substringWithRange:NSMakeRange(NSMaxRange(range), lineRange.length - range.length)];
				
				if (workspaces != nil) {
					NSArray *paths = [workspaces componentsSeparatedByString:@","];
					NSEnumerator *e = [paths objectEnumerator];
					NSString *path;
					NSMutableArray *children = [NSMutableArray arrayWithCapacity:1];
					BOOL isDir;
					NSFileManager *fileManager = [NSFileManager defaultManager];

					while (path = [e nextObject]) {
						if ([fileManager fileExistsAtPath:path isDirectory:&isDir] && isDir) {
							QSObject *child = [self newWorkspace:path];
							//set the parent path so that when opened it opens with the correct eclipse instance
							[child setObject:eclipsePath forType:QSEclipseParentEclipse];
							[children addObject:child];
						}
					}
					
					if ([children count] > 0) {
						[object setChildren:children];
					}
				}
			}
			
			[contents release];
			return YES;
		} else {
			// an error occurred
			NSLog(@"Error reading file at %@\n%@",
					eclipsePath, [error localizedFailureReason]);
		}
	}
	
	return NO;
}

@end
